﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Data.SQLite;


namespace ufolder
{
    public partial class FormMain : Form
    {
        private SQLiteConnection _connection = new SQLiteConnection("Data Source=data.db3;Version=3;");
        private TagsPalette tp;

        public FormMain()
        {
            InitializeComponent();
            lBResult.Invalidate();
            this._connection.Open();
            
            Version v = new Version(Application.ProductVersion);
            this.Text = "UFolder [" + v.Major.ToString() + "." + v.Minor.ToString() + "." + v.Build.ToString() + "." + v.Revision.ToString() + "]";

            Search();
        }

        private void lBResult_DrawItem(object sender, DrawItemEventArgs e)
        {
            if (e.Index != -1)
            {
                int space = e.Font.Height;
                int TagSpace = 2;
                int TagBackLineSize = 2;
                int LineCharMax = 60;
                Color BackLineColor = Color.FromArgb(255, 250, 240);

                string titre = ((Item)lBResult.Items[e.Index]).Titre;
                string texte = ((Item)lBResult.Items[e.Index]).Texte;
                string date = ((Item)lBResult.Items[e.Index]).Date;
                string uri = ((Item)lBResult.Items[e.Index]).URI;

                if (texte != null && texte != "")
                {
                    texte = texte.Replace("\r", ""); texte = texte.Replace("\n", "");
                    texte = texte.Substring(0, texte.Length < LineCharMax ? texte.Length : LineCharMax);
                }

                Font tagFont = new Font(e.Font, FontStyle.Italic);

                if (e.Index % 2 == 0)
                    e.Graphics.FillRectangle(new SolidBrush(BackLineColor), e.Bounds);
                else
                    e.Graphics.FillRectangle(new SolidBrush(Color.White), e.Bounds);

                //Draw de la date et du titre et texte
                float dateWidth = e.Graphics.MeasureString(date, e.Font).Width;
                float titreWidth = e.Graphics.MeasureString(titre, e.Font).Width;
                float texteWidth = e.Graphics.MeasureString(texte, tagFont).Width;

                Color DateColor = (e.Index % 2 == 0 ? Color.LightBlue : Color.LightCyan);
                Color TitreColor = (e.Index % 2 == 0 ? Color.PeachPuff : Color.PapayaWhip);


                //Background et date:
                e.Graphics.FillRectangle(new SolidBrush(DateColor), 0, e.Bounds.Y, dateWidth, e.Font.Height);
                e.Graphics.DrawString(date, e.Font, Brushes.Black, e.Bounds.X, e.Bounds.Y);

                //Background du titre:
                e.Graphics.FillRectangle(new SolidBrush(TitreColor), dateWidth + 5, e.Bounds.Y, titreWidth, e.Font.Height);
                
                e.Graphics.FillPolygon((uri=="")?new SolidBrush(TitreColor):new SolidBrush(Color.SandyBrown), new Point[] {new Point((int)(titreWidth+dateWidth)+5, (int)e.Bounds.Y), 
                        new Point ((int)(titreWidth+dateWidth)+5, e.Bounds.Y+e.Font.Height), new Point((int)(titreWidth+dateWidth)+15, (e.Bounds.Y+e.Bounds.Y+e.Font.Height)>>1)});

                e.Graphics.DrawString(titre, e.Font, Brushes.Black, (int)dateWidth + e.Bounds.X+10, e.Bounds.Y);

                //Texte:
                e.Graphics.DrawString(texte, tagFont, Brushes.Black, dateWidth+titreWidth + 15, e.Bounds.Y); 
                
                //Draw des labels

                int nbrTag = ((Item)lBResult.Items[e.Index]).Tags.Length;
                int offset = (int)(dateWidth+titreWidth + texteWidth) + 25;

                for (int i = 0; i < nbrTag; i++)
                {
                    Label t = ((Item)lBResult.Items[e.Index]).Tags[i];
                    SolidBrush BackBrush = new SolidBrush(t.TagColor);
                    Rectangle rectToFill = new Rectangle(offset + TagSpace, e.Bounds.Y + TagBackLineSize, (int)e.Graphics.MeasureString(t.Tag, tagFont).Width, e.Bounds.Height - TagBackLineSize);

                    float OffsetGaucheEcriture = offset + TagSpace;

                    e.Graphics.FillRectangle(BackBrush, rectToFill);


                    e.Graphics.DrawString(t.Tag, tagFont, Brushes.Black, OffsetGaucheEcriture, e.Bounds.Y);

                    offset += rectToFill.Width + TagSpace;
                }
            }
        }

        private void tSBPalette_Click(object sender, EventArgs e)
        {
            tSBPalette.Checked = !tSBPalette.Checked;

            if (tSBPalette.Checked)
            {
                this.tp = new TagsPalette();
                this.tp.Display(Label.FinAllAndLinked(this._connection));
                this.tp.Show();
                this.Focus();

            }
            else
            {
                this.tp.Hide();
                this.tp.Dispose();
            }


        }

        private void tBSeek_Click(object sender, EventArgs e)
        {

        }

        private void lBResult_SelectedValueChanged(object sender, EventArgs e)
        {
            if (lBResult.SelectedIndex != -1)
            {
                AddUpdateForm auf = new AddUpdateForm();
                auf.DisplayItem((Item)lBResult.Items[lBResult.SelectedIndex]);
                auf.FormClosed += new FormClosedEventHandler(auf_FormClosed_Mod);
                auf.ShowDel();
                auf.Show();
            }
            
        }

        void auf_FormClosed_Mod(object sender, FormClosedEventArgs e)
        {
            AddUpdateForm auf = (AddUpdateForm)sender;

            switch (auf.DialogResult)
            {
                case DialogResult.Abort:
                    auf.DisplayedItem.Delete(this._connection);
                    break;
                case DialogResult.OK:
                    ArrayList al = new ArrayList();
                    if (auf.Tags != null)
                    {
                        
                        foreach (string s in auf.Tags)
                        {
                            al.Add(new Label(s, this._connection));
                        }
                    }
                    auf.DisplayedItem.Modify(this._connection, auf.Titre, auf.Texte, auf.URI, auf.Type, (Label[])al.ToArray(typeof(Label)));
                    break;
            }
            auf.Dispose();
            Search();
        }

        private void tSBAdd_Click(object sender, EventArgs e)
        {
            AddUpdateForm auf = new AddUpdateForm();
            auf.FormClosed += new FormClosedEventHandler(auf_FormClosed);
            auf.Show();
        }

        void auf_FormClosed(object sender, FormClosedEventArgs e)
        {
            AddUpdateForm auf = (AddUpdateForm)sender;
            if (auf.DialogResult == DialogResult.OK)
            {
                ArrayList al = new ArrayList();
                if (auf.Tags!=null)
                {
                    foreach (string s in auf.Tags)
                    {
                        al.Add(new Label(s, this._connection));
                    }
                }
                Item.Create(this._connection, auf.Titre, auf.URI, auf.Texte, auf.Type, (Label[])al.ToArray(typeof(Label)));

                Search();
            }
            auf.Dispose();
        }

        private void tSBStruct_Click(object sender, EventArgs e)
        {
            StructForm sf = new StructForm();
            sf.InitTagDisplay(this._connection);
            sf.FormClosed += new FormClosedEventHandler(sf_FormClosed);
            sf.TagStructModified += new StructForm.TagStrucModifiedDelegate(sf_TagStructModified);
            sf.TagDoubleClicked += new StructForm.TagDoubleClickedDelegate(sf_TagDoubleClicked);
            sf.Show();
        }

        void sf_TagDoubleClicked(string label)
        {
            this.tBSeek.Text = "tag:<" + label;
            Search();
        }

        void sf_TagStructModified()
        {
            Search();
        }

        void sf_FormClosed(object sender, FormClosedEventArgs e)
        {
            StructForm sf = (StructForm) sender;
            sf.Dispose();
        }

        private void FormMain_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                notifyIcon.Visible = true;
                this.Hide();
                this.ShowInTaskbar = false;
            }
            else if (this.WindowState == FormWindowState.Normal)
            {
                notifyIcon.Visible = false;
            }

        }

        private void notifyIcon1_DoubleClick(object sender, EventArgs e)
        {

            this.Show();
            this.Visible = true;
            this.Activate();
            if (this.WindowState == FormWindowState.Minimized)
                this.WindowState = FormWindowState.Normal;
            notifyIcon.Visible = false;
            this.ShowInTaskbar = true;
        }

        private void quitterToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
            this.Dispose();
        }

        private void Search()
        {
            tBSeek.BackColor = Color.White;
            try
            {
                Item[] resultSet = Item.Seek(_connection, this.tBSeek.Text);
                lBResult.DisplayResult(resultSet);
                //lBResult.Focus();
            }
            catch (ParserException)
            {
                tBSeek.BackColor = Color.Red;
            }
        }

        private void tBSeek_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == '\r')
            {
                e.Handled = true;
                Search();
            }
        }
    }
}

